package com.googlecode.vmock.proxy;

import com.googlecode.vmock.exceptions.ProxyInstantiationException;
import com.googlecode.vmock.utils.Validate;

/**
 * Factory class that delivers proxy objects of a given type. It uses a singleton pattern, but allows the end user to change the singleton for a
 * different implementation if necessary. By default, the singleton is {@link VMockProxyFactory} object.
 * 
 * @author marcin.jagus
 */
public abstract class ProxyFactory {

    /**
     * One and only instance of a proxy factory.
     */
    private static ProxyFactory INSTANCE = new VMockProxyFactory();

    protected ProxyFactory() {
    }

    /**
     * Returns one and only instance of a proxy factory.
     * 
     * @return One and only instancje of a proxy factory.
     */
    public static ProxyFactory getInstance() {
        return INSTANCE;
    }

    /**
     * Changes the one and only instance of a proxy factory for a given one.
     * 
     * @param proxyFactory New proxy factory. Cannot be <code>null</code>.
     */
    public static void setInstance(ProxyFactory proxyFactory) {
        Validate.notNull(proxyFactory, "proxyFactory == null");
        INSTANCE = proxyFactory;
    }

    /**
     * Creates a proxy object that's an instance of a given type. May throw {@link ProxyInstantiationException} if proxy object cannot be created for
     * some reason.
     * 
     * @param clazz Given type
     * @return Proxy object of a given type
     */
    public abstract <T> T createProxy(Class<T> clazz);
}